package com.fowo.api.common.excel;

import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import org.springframework.util.StringUtils;

import javax.annotation.Nullable;
import java.util.*;

/**
 * 用于把 Map 列表直接导出为 Excel
 * @author yl_ls
 */
public class ListMapExcelExport {

    public static void writeFromScriptResult(ExcelWriterSheetBuilder writerSheetBuilder, Object scriptResult) {
        if (scriptResult instanceof List) {
            write(writerSheetBuilder, null, (List<?>) scriptResult);
        } else if (scriptResult instanceof Map) {
            Map map = (Map)scriptResult;
            write(writerSheetBuilder, (List<?>) map.get("columns"), (List<?>) map.get("rows"));
        }
    }

    public static void write(ExcelWriterSheetBuilder writerSheetBuilder, List<?> list) {
        write(writerSheetBuilder, null, list);
    }

    public static void write(ExcelWriterSheetBuilder writerSheetBuilder, @Nullable List<?> columns, List<?> list) {
        if (list.isEmpty()) {
            return;
        }
        Object firstRow = list.get(0);
        if (!Map.class.isAssignableFrom(firstRow.getClass())) {
            return;
        }

        Map<String, Integer> headMaps = new HashMap<>();
        List<List<String>> head = new ArrayList<>();
        List<List<Object>> cells = new ArrayList<>();
        if (columns != null) {
            for (int i = 0; i < columns.size(); i++) {
                String columnName = getColumnNameFromColumn(columns.get(i));
                head.add(Collections.singletonList(columnName));
                if (StringUtils.hasText(columnName)) {
                    headMaps.put(columnName, i);
                }
            }
        } else {
            int colIndex = 0;
            for (Object o : ((Map) firstRow).keySet()) {
                if (o instanceof String) {
                    headMaps.put((String) o, colIndex);
                    head.add(Collections.singletonList((String) o));
                    colIndex++;
                }
            }
        }

        for(Object row : list) {
            List<Object> rowCells = new ArrayList<>(head.size());
            for (int i = 0; i < head.size(); i++) {
                rowCells.add(null);
            }
            cells.add(rowCells);
            Map map = (Map)row;
            for (Map.Entry<String, Integer> colMap : headMaps.entrySet()) {
                Object val = map.get(colMap.getKey());
                Integer cellIndex = colMap.getValue();
                if (val != null) {
                    rowCells.set(cellIndex, val);
                } else {
                    rowCells.set(cellIndex, null);
                }
            }
        }

        writerSheetBuilder.head(head).doWrite(cells);
    }

    private static String getColumnNameFromColumn(Object column) {
        if (column instanceof String) {
            return (String)column;
        }
        return null;
    }
}
